package com.vagavaga.tx;

import java.util.HashMap;


/**
 * This is utility class that keep track of thread transactions.
 * 
 * @author <code>river</code>
 * @version $Revision: 1.5 $ $Date: 2004/11/07 00:00:27 $
 */

final class TransactionManager {
    /**
     * ThreadLocal that keeps track of current thread transaction.
     */
    private static ThreadLocal<HashMap<String, Transaction>> currentTransaction = new ThreadLocal<HashMap<String, Transaction>>() {
        @Override
        protected HashMap<String, Transaction> initialValue() {
            return new HashMap<String, Transaction>();
        }
    };

    /**
     * Private constructor to prevent instantiation of this class.
     */
    private TransactionManager() {
    // no instantiation
    }

    /**
     * Returns calling threads current transaction.
     * 
     * @return Calling threads transaction, or null if there is no transaction.
     */
    public static Transaction getCurrentTransaction(String dsname) {
        return currentTransaction.get().get(dsname);
    }

    /**
     * Registers calling thread with <code>transaction</code>. Only one
     * transaction can be associated with thread at any time.
     * 
     * @param transaction
     *        Transaction to associate with current thread.
     * @throws IllegalStateException
     *         if thread is already associated with transaction.
     */
    public static void bind(String dsname, Transaction transaction) throws IllegalStateException {
        if (isInTransaction(dsname)) { throw new IllegalStateException("Thread is already in transaction"); }
        currentTransaction.get().put(dsname, transaction);
    }

    /**
     * Deregister calling thread if he is registrated with some transaction.
     */
    public static void unbind(String dsname) {
        currentTransaction.get().remove(dsname);
    }

    /**
     * Tests if calling thread is associated with any transaction.
     * 
     * @return true if thread is associated with transaction, false otherwise.
     */
    public static boolean isInTransaction(String dsname) {
        return getCurrentTransaction(dsname) != null;
    }
}
